package cn.mybatishelper.entity.java;

import cn.mybatishelper.entity.database.DatabaseEntity;
import cn.mybatishelper.entity.mybatis.MybatisElement;
import cn.mybatishelper.entity.xml.MybatisXmlEntity;
import cn.mybatishelper.exception.MybatisHelperException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * 用于生成mapper.java
 *
 * @author GameKing
 */
public class MapperEntity extends JavaEntity {
    /**
     * 继承的父类的完整路径名
     */
    private String extendsClassUrl = null;
    /**
     * xml解析器，包含需要生成的xml文件的元素组成，当extendsClassUrl为null时，需要通过这些元素来生成方法
     */
    private MybatisXmlEntity mybatisXmlEntity;

    public MapperEntity() {
        super();
    }

    public MapperEntity(String extendsClassUrl, MybatisXmlEntity mybatisXmlEntity) {
        this.extendsClassUrl = extendsClassUrl;
        this.mybatisXmlEntity = mybatisXmlEntity;
    }

    public MapperEntity(String rootFilePath, String extendsClassUrl, MybatisXmlEntity mybatisXmlEntity) {
        super(rootFilePath);
        this.extendsClassUrl = extendsClassUrl;
        this.mybatisXmlEntity = mybatisXmlEntity;
    }

    @Override
    public String toCodeString(DatabaseEntity databaseEntity) {
        if (!validateDatabaseEntity(databaseEntity)) {
            return null;
        }
        LOGGER.info("开始转化表：" + databaseEntity.getTableName() + "的Mapper类内容...");

        if (StringUtils.isEmpty(extendsClassUrl)) {
            LOGGER.warn(databaseEntity.getTableName() + "实体的extendsClassUrl属性为空，生成的mapper将不会继承任何父类...");
        }

        StringBuilder str = new StringBuilder();
        str.append("package " + databaseEntity.getXmlPackageName() + ";\n");
        str.append("\n");
        str.append("import " + databaseEntity.getJavaPackageName() + "." + databaseEntity.getObjectName() + ";\n");
        if (validateExtendsClassUrl()) {
            str.append("import " + extendsClassUrl + ";\n");
        }
        str.append("\n\n");
        str.append("public interface " + databaseEntity.getObjectName() + "Mapper");
        if (validateExtendsClassUrl()) {
            String[] strs = extendsClassUrl.split("\\.");
            str.append(" extends " + strs[strs.length - 1] + "<" + databaseEntity.getObjectName() + ">");
        }
        str.append("{\n");
        if (!validateExtendsClassUrl() && mybatisXmlEntity != null) {
            List<MybatisElement> elements = mybatisXmlEntity.getElements();
            if (elements != null && elements.size() > 0) {
                for (MybatisElement element : elements) {
                    if (element.isMethod()) {
                        str.append("\n");
                        str.append(element.toCodeString());
                    }
                }
            }
        }
        str.append("\n");
        str.append("}\n");
        return str.toString();
    }

    /**
     * 校验数据库实体是否有效*
     */
    public boolean validateDatabaseEntity(DatabaseEntity databaseEntity) {
        if (databaseEntity == null) {
            LOGGER.error("初始化Entity元素时，databaseEntity为null!");
            return false;
        }
        if (!databaseEntity.validateAndCompleteEntity()) {
            LOGGER.error("初始化Entity元素时，databaseEntity验证无效!");
            return false;
        }
        if (StringUtils.isBlank(rootFilePath)) {
            LOGGER.error("文件根路径不能为空");
            return false;
        }
        if (StringUtils.isBlank(extendsClassUrl) && mybatisXmlEntity == null) {
            LOGGER.error("mapper接口所继承的父类附近和mybatis的xml实例不能同时为null");
            return false;
        }
        return true;
    }

    /**
     * 验证extendsClassUrl是否为Null
     *
     * @return
     */
    private boolean validateExtendsClassUrl() {
        return extendsClassUrl != null && !"".equals(extendsClassUrl);
    }

    /**
     * ************get/set*************
     */
    public String getExtendsClassUrl() {
        return extendsClassUrl;
    }

    public void setExtendsClassUrl(String extendsClassUrl) {
        this.extendsClassUrl = extendsClassUrl;
    }

    public MybatisXmlEntity getMybatisXmlEntity() {
        return mybatisXmlEntity;
    }

    public void setMybatisXmlEntity(MybatisXmlEntity mybatisXmlEntity) {
        this.mybatisXmlEntity = mybatisXmlEntity;
    }

    @Override
    public void createFile(DatabaseEntity databaseEntity) throws MybatisHelperException {
        try {
            String content = this.toCodeString(databaseEntity);
            String packageUrl = databaseEntity.getXmlPackageName().replaceAll("\\.", "/");
            File file = new File(rootFilePath + File.separator + packageUrl + File.separator + databaseEntity.getObjectName() + "Mapper.java");
            FileUtils.writeStringToFile(file, content, "UTF-8");
        } catch (IOException e) {
            throw new MybatisHelperException("转化物理文件发生异常 : " + e.getMessage());
        }
    }
}
